//
//  BBROIConfigView.m
//  BBTouch
//
//  Created by ben smith on 6/14/08.
//  This file is part of BBTouch.
//
//  BBTouch is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.

//  BBTouch is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.

//  You should have received a copy of the GNU Lesser General Public License
//  along with BBTouch.  If not, see <http://www.gnu.org/licenses/>.
// 
//  Copyright 2008 Ben Britten Smith ben@benbritten.com .
//
//

#import "BBROIConfigView.h"
#import "BBConfigurationController.h"

#define BB_HANDLE_RADIUS 10
#define BB_INNER 1
#define BB_LEFT_HANDLE 2
#define BB_RIGHT_HANDLE 3
#define BB_TOP_HANDLE 4
#define BB_BOTTOM_HANDLE 5

@implementation BBROIConfigView

- (void)drawRect:(NSRect)rect 
{	
	[super drawRect:rect];
	
	// draw the current ROI
	[NSBezierPath setDefaultLineWidth:2.0];
	NSRect roiRect = [[BBConfigurationController sharedConfigurationController] regionOfInterest];
	[[NSColor redColor] set];
	[NSBezierPath strokeRect:roiRect];
}

-(void)resetCursorRects
{
	[super resetCursorRects];
	if (mouseDragging) {
		[self addCursorRect:[self bounds] cursor:[NSCursor currentCursor]];
		return;
	}
	NSRect roiRect = [[BBConfigurationController sharedConfigurationController] regionOfInterest];

	// the move-it-all-around cursor
	[self addCursorRect:[self innerRectWithROI:roiRect] cursor:[NSCursor openHandCursor]];

	// left side handle
	[self addCursorRect:[self leftHandleWithROI:roiRect] cursor:[NSCursor resizeLeftRightCursor]];
	// right side handle
	[self addCursorRect:[self rightHandleWithROI:roiRect] cursor:[NSCursor resizeLeftRightCursor]];
	
	// top side handle
	[self addCursorRect:[self topHandleWithROI:roiRect] cursor:[NSCursor resizeUpDownCursor]];
	// bottom side handle
	[self addCursorRect:[self bottomHandleWithROI:roiRect] cursor:[NSCursor resizeUpDownCursor]];
}

// some convenience methods for the cursor rects and the mouseDrag methods
-(NSRect)innerRectWithROI:(NSRect)roiRect
{
	return NSInsetRect(roiRect,(BB_HANDLE_RADIUS * 2.0), (BB_HANDLE_RADIUS * 2.0));
}

-(NSRect)leftHandleWithROI:(NSRect)roiRect
{
	return NSMakeRect(NSMinX(roiRect) - BB_HANDLE_RADIUS, NSMinY(roiRect), (BB_HANDLE_RADIUS * 2.0), roiRect.size.height);
}

-(NSRect)rightHandleWithROI:(NSRect)roiRect
{
	return NSMakeRect(NSMaxX(roiRect) - BB_HANDLE_RADIUS, NSMinY(roiRect), (BB_HANDLE_RADIUS * 2.0), roiRect.size.height);
}

-(NSRect)bottomHandleWithROI:(NSRect)roiRect
{
	return NSMakeRect(NSMinX(roiRect), NSMinY(roiRect) - BB_HANDLE_RADIUS,roiRect.size.width,(BB_HANDLE_RADIUS * 2.0));
}

-(NSRect)topHandleWithROI:(NSRect)roiRect
{
	return NSMakeRect(NSMinX(roiRect), NSMaxY(roiRect) - BB_HANDLE_RADIUS,roiRect.size.width,(BB_HANDLE_RADIUS * 2.0));
}

///////////////////////////////////////
// mouse events

-(void)mouseDown:(NSEvent *)theEvent
{
	mouseDown = [[[self window] contentView] convertPoint:[theEvent locationInWindow] toView:self];
	NSRect roiRect = [[BBConfigurationController sharedConfigurationController] regionOfInterest];
	handle = 0;
	// figure out where i hit and do something about it
	if (NSPointInRect(mouseDown, [self innerRectWithROI:roiRect])) {
		handle = BB_INNER;
	}
	if (NSPointInRect(mouseDown, [self leftHandleWithROI:roiRect])) {
		handle = BB_LEFT_HANDLE;
	}
	if (NSPointInRect(mouseDown, [self rightHandleWithROI:roiRect])) {
		handle = BB_RIGHT_HANDLE;
	}
	if (NSPointInRect(mouseDown, [self topHandleWithROI:roiRect])) {
		handle = BB_TOP_HANDLE;
	}
	if (NSPointInRect(mouseDown, [self bottomHandleWithROI:roiRect])) {
		handle = BB_BOTTOM_HANDLE;
	}
	mouseDragging = YES;
}

-(void)mouseUp:(NSEvent *)theEvent
{
	// clean up the mousie stuff
	handle = 0;
	mouseDragging = NO;
	[[self window] invalidateCursorRectsForView:self];
	[self setNeedsDisplay:YES];
}

// this is by no means the best or fastest way to do this, but it is simple and
// easy to follow (and easy to change).  Also the performance in the ROI Configurator
// is not really worth any further optimizations
- (void)mouseDragged:(NSEvent *)theEvent
{
	mouseDragging = YES;
	if (handle == 0) return;
	// change the ROI
	// first, what are we doing?
	NSPoint mouseLoc = [[[self window] contentView] convertPoint:[theEvent locationInWindow] toView:self];
	NSRect roiRect = [[BBConfigurationController sharedConfigurationController] regionOfInterest];
	// dont use deltaX or deltaY because my view is scaled
	switch (handle) {
		case BB_INNER:
			roiRect.origin.x += mouseLoc.x - mouseDown.x;
			roiRect.origin.y += mouseLoc.y - mouseDown.y;		
			break;
		case BB_LEFT_HANDLE:
			roiRect.origin.x += mouseLoc.x - mouseDown.x;
			roiRect.size.width -= mouseLoc.x - mouseDown.x;
			break;
		case BB_RIGHT_HANDLE:
			roiRect.size.width += mouseLoc.x - mouseDown.x;
			break;
		case BB_TOP_HANDLE:
			roiRect.size.height += mouseLoc.y - mouseDown.y;
			break;
		case BB_BOTTOM_HANDLE:
			roiRect.origin.y += mouseLoc.y - mouseDown.y;
			roiRect.size.height -= mouseLoc.y - mouseDown.y;
			break;
	}
	
	[[BBConfigurationController sharedConfigurationController] setRegionOfInterest:roiRect];
	[[self window] invalidateCursorRectsForView:self];
	[self setNeedsDisplay:YES];
	mouseDown = mouseLoc;
}

@end
